/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
package openbackup.oracle.livemount;

import lombok.extern.slf4j.Slf4j;
import openbackup.data.access.framework.livemount.common.model.LiveMountFileSystemShareInfo;
import openbackup.data.access.framework.livemount.common.model.LiveMountObject;
import openbackup.data.access.framework.livemount.provider.DefaultLiveMountServiceProvider;
import openbackup.data.protection.access.provider.sdk.backup.BackupTypeConstants;
import openbackup.system.base.common.constants.CommonErrorCode;
import openbackup.system.base.common.constants.SymbolConstant;
import openbackup.system.base.common.exception.LegoCheckedException;
import openbackup.system.base.common.model.livemount.LiveMountEntity;
import openbackup.system.base.common.utils.JSONArray;
import openbackup.system.base.common.utils.VerifyUtil;
import openbackup.system.base.sdk.copy.CopyRestApi;
import openbackup.system.base.sdk.copy.model.Copy;
import openbackup.system.base.sdk.copy.model.CopyGeneratedByEnum;
import openbackup.system.base.sdk.resource.model.ResourceEntity;
import openbackup.system.base.sdk.resource.model.ResourceSubTypeEnum;
import openbackup.system.base.util.BeanTools;

import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;

/**
 * Oracle即时挂载服务provider
 *
 */
@Slf4j
@Component
public class OracleLiveMountServiceProvider extends DefaultLiveMountServiceProvider {
    private final CopyRestApi copyRestApi;

    public OracleLiveMountServiceProvider(CopyRestApi copyRestApi) {
        this.copyRestApi = copyRestApi;
    }

    @Override
    public boolean applicable(String subType) {
        return ResourceSubTypeEnum.ORACLE.equalsSubType(subType)
                || ResourceSubTypeEnum.ORACLE_CLUSTER.equalsSubType(subType);
    }

    @Override
    public boolean isSourceCopyCanBeMounted(Copy copy, boolean isManual) {
        boolean isSourceCopyCanBeMounted = super.isSourceCopyCanBeMounted(copy, isManual);
        if (copy.getSourceCopyType() == BackupTypeConstants.LOG.getAbBackupType()) {
            if (!isManual) {
                return false;
            }
            throw new LegoCheckedException(CommonErrorCode.OBJ_NOT_EXIST, "latest log copy is not available.");
        }
        return isSourceCopyCanBeMounted;
    }

    @Override
    public LiveMountEntity buildLiveMountEntity(LiveMountObject liveMountObject, ResourceEntity sourceResourceEntity,
        ResourceEntity targetResourceEntity) {
        log.info("oracle build live mount entity start.copy id:{}, source id:{}, target id:{}",
            liveMountObject.getCopyId(), sourceResourceEntity.getUuid(), targetResourceEntity.getUuid());
        LiveMountEntity entity = super.buildLiveMountEntity(liveMountObject, sourceResourceEntity,
            targetResourceEntity);
        LiveMountObject deepCopyLiveMountObject = BeanTools.deepClone(liveMountObject);
        List<LiveMountFileSystemShareInfo> fileSystemShareInfoList =
            deepCopyLiveMountObject.getFileSystemShareInfoList();
        if (VerifyUtil.isEmpty(fileSystemShareInfoList)) {
            return entity;
        }
        Copy copy = copyRestApi.queryCopyByID(liveMountObject.getCopyId());
        // 即时挂载副本不会再次克隆副本，使用原副本的文件系统名称
        if (Objects.isNull(copy) || CopyGeneratedByEnum.BY_LIVE_MOUNTE.value().equals(copy.getGeneratedBy())) {
            log.info("copy is null or generated by live mount.");
            return entity;
        }
        for (LiveMountFileSystemShareInfo shareInfo : fileSystemShareInfoList) {
            shareInfo.setFileSystemName(
                shareInfo.getFileSystemName() + SymbolConstant.UNDERLINE + targetResourceEntity.getUuid());
            log.info("Oracle getFileSystemName {}, uuid {}.", shareInfo.getFileSystemName(),
                targetResourceEntity.getUuid());
        }
        entity.setFileSystemShareInfo(JSONArray.fromObject(fileSystemShareInfoList).toString());
        return entity;
    }

    @Override
    public boolean isSupportLogCopy() {
        return false;
    }
}